package com.kerrykidz.sales.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.kerrykidz.common.ORDER_CONSTANTS;
import com.kerrykidz.common.PrimaryKeyGenerator;
import com.kerrykidz.filemanagement.dao.model.HisOrderEntity;
import com.kerrykidz.membership.dao.model.CusGuaEntity;
import com.kerrykidz.membership.service.IMemberService;
import com.kerrykidz.sales.dao.mapper.PosOrderEntityMapper;
import com.kerrykidz.sales.dao.mapper.PosOrderPaymentEntityMapper;
import com.kerrykidz.sales.dao.model.PosOrderEntity;
import com.kerrykidz.sales.dao.model.PosOrderPaymentEntity;
import com.kerrykidz.sales.service.IOrderService;
import com.kerrykidz.sales.service.IPaymentService;
import com.rdp.framework.exception.RDPException;

@Service
public class PaymentServiceImpl implements IPaymentService {

	private Logger logger = Logger.getLogger(PaymentServiceImpl.class);

	@Autowired
	private PosOrderPaymentEntityMapper posOrderPaymentEntityMapper;

	@Autowired
	private PosOrderEntityMapper posOrderEntityMapper;

	@Autowired
	private IOrderService orderService;

	@Autowired
	private IMemberService memberService;

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Override
	public List<PosOrderPaymentEntity> findByOrderPk(String orderId)
			throws Exception {
		PosOrderPaymentEntity entity = new PosOrderPaymentEntity();
		entity.setFkOrderId(orderId);
		return this.posOrderPaymentEntityMapper.findByEntity(entity);
	}

	private void updateOrderModiTime(String orderId) {
		PosOrderEntity order = new PosOrderEntity();
		order.setPkOrderId(orderId);
		order.setModiTime(new Date());
		this.posOrderEntityMapper.updateByPrimaryKeySelective(order);
	}

	@Override
	public void createPayment(PosOrderPaymentEntity payment) throws Exception {

		if (StringUtils.isBlank(payment.getPayMethod())) {
			throw new Exception("支付方式不能为空");
		} else if (payment.getAmount() == null) {
			throw new Exception("金额不能为空");
		} else if (StringUtils.isBlank(payment.getFkAccount())) {
			throw new Exception("付款账户不能为空");
		} else if (StringUtils.isBlank(payment.getFkOrderId())) {
			throw new Exception("订单不能为空");
		} else if (StringUtils.isBlank(payment.getFkBranId())) {
			throw new Exception("分店不能为空");
		}
		// 检查是否是余额支付,如果是需要检查余额
		if (ORDER_CONSTANTS.PAY_METHOD_BALANCE.equals(payment.getPayMethod())) {
			synchronized (payment.getFkAccount()) {
				double balance = this.findCustomerBalance(payment
						.getFkAccount());
				if (balance < payment.getAmount()) {
					throw new Exception("余额不足");
				}
				this.changeBalance(payment.getFkAccount(),
						-Math.abs(payment.getAmount()));
			}
		}

		payment.setPkPaymentId(PrimaryKeyGenerator.getRandomPrimaryKey());
		payment.setPayTime(new Date());
		payment.setModiTime(new Date());

		this.posOrderPaymentEntityMapper.insert(payment);

		this.posOrderEntityMapper.finishPayment(payment.getFkOrderId());

		this.updateOrderModiTime(payment.getFkOrderId());
		this.logger.info("订单[" + payment.getFkOrderId() + "]已支付成功!");
	}

	@Override
	public double findCustomerBalance(String memId) throws Exception {
		String sql = "SELECT CAN_CONSUME,BALANCE FROM CUS_MEM WHERE PK_MEM_ID=?";
		Map<String, Object> map = this.jdbcTemplate.queryForMap(sql, memId);
		if ("1".equals(map.get("CAN_CONSUME"))) { // 可消费余额
			Double d = (Double) map.get("BALANCE");
			return d != null ? d : 0;
		} else
			throw new Exception("不可消费余额");
	}

	@Override
	public boolean changeBalance(String memId, double money) {
		String sql = "UPDATE CUS_MEM SET BALANCE= BALANCE+(?) WHERE PK_MEM_ID=?";
		this.jdbcTemplate.update(sql, money, memId);
		return true;
	}

	@Override
	public synchronized void createPayments(
			List<PosOrderPaymentEntity> payments, String orderId, boolean isPrepay)
			throws Exception {
		for (PosOrderPaymentEntity payment : payments) {
			if (StringUtils.isBlank(payment.getPayMethod())) {
				throw new Exception("支付方式不能为空");
			} else if (payment.getAmount() == null) {
				throw new Exception("金额不能为空");
				// } else if (StringUtils.isBlank(payment.getFkAccount())) {
				// throw new Exception("付款账户不能为空");
			} else if (StringUtils.isBlank(payment.getFkOrderId())) {
				throw new Exception("订单不能为空");
			} else if (StringUtils.isBlank(payment.getFkBranId())) {
				throw new Exception("分店不能为空");
			}
			// 检查是否是余额支付,如果是需要检查余额
			if (ORDER_CONSTANTS.PAY_METHOD_BALANCE.equals(payment.getPayMethod())) {

				if (StringUtils.isBlank(payment.getFkAccount()))
					throw new Exception("付款账户不能为空");
				else if (StringUtils.isBlank(payment.getFkPayer()))
					throw new Exception("付款人不能为空");
				double balance = this.findCustomerBalance(payment
						.getFkAccount());
				if (balance < payment.getAmount()) {
					throw new Exception("余额不足");
				}
				this.changeBalance(payment.getFkAccount(), -Math.abs(payment.getAmount()));
			}
			payment.setPkPaymentId(PrimaryKeyGenerator.getRandomPrimaryKey());
			payment.setPayTime(new Date());
			payment.setModiTime(new Date());

		}
		this.posOrderPaymentEntityMapper.batchInsert(payments);
		if (!isPrepay)
			this.posOrderEntityMapper.finishPayment(orderId);
		this.memberService.createMemHis(orderId);

		this.updateOrderModiTime(orderId);
		this.logger.info("订单[" + orderId + "]已支付成功!");
	}

	@Override
	public boolean isPay(String orderId) {
		PosOrderEntity order = this.orderService.findOrderByPk(orderId);
		return order != null && ORDER_CONSTANTS.ORDER_STATUS_HAS_BEEN_PAY.equals(order.getOrderStatus());
	}

	@Override
	public List<Map<String, Object>> countTodayIncome(String branId) {
		String sql = "SELECT a.PAY_METHOD as P,sum(a.AMOUNT) AS V FROM pos_order_payment a  inner join pos_order b on a.FK_ORDER_ID = b.PK_ORDER_ID ";
		sql += " where a.PAY_TIME > ? and b.ORDER_STATUS=? and b.fk_bran_id=? group by a.PAY_METHOD";
		Date today = new Date();
		Calendar c = Calendar.getInstance();
		c.setTime(today);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		List<Map<String, Object>> list = this.jdbcTemplate.queryForList(sql,
				c.getTime(), ORDER_CONSTANTS.ORDER_STATUS_HAS_BEEN_PAY, branId);
		return list;
	}

	@Override
	public void createRepay(PosOrderPaymentEntity payment) throws Exception {
		List<PosOrderPaymentEntity> list = new ArrayList<PosOrderPaymentEntity>();
		if (StringUtils.isBlank(payment.getPayMethod())) {
			throw new Exception("支付方式不能为空");
		} else if (payment.getAmount() == null) {
			throw new Exception("金额不能为空");
		} else if (StringUtils.isBlank(payment.getFkOrderId())) {
			throw new Exception("订单不能为空");
		} else if (StringUtils.isBlank(payment.getFkBranId())) {
			throw new Exception("分店不能为空");
		}
		// 检查是否是余额支付,如果是需要检查余额
		if (ORDER_CONSTANTS.PAY_METHOD_BALANCE.equals(payment.getPayMethod())) {
			double balance = this.findCustomerBalance(payment.getFkAccount());
			if (balance < payment.getAmount()) {
				throw new Exception("余额不足");
			} else if (StringUtils.isBlank(payment.getFkAccount())) {
				throw new Exception("付款账户不能为空");
			}
			this.changeBalance(payment.getFkAccount(),
					-Math.abs(payment.getAmount()));
		}
		payment.setPayTime(new Date());
		payment.setPkPaymentId(PrimaryKeyGenerator.getRandomPrimaryKey());
		payment.setModiTime(new Date());

		list.add(payment);
		this.posOrderPaymentEntityMapper.batchInsert(list);
		this.posOrderEntityMapper.repayPayment(payment.getFkOrderId(), payment.getAmount());
		this.updateOrderModiTime(payment.getFkOrderId());
	}

	@Override
	public PosOrderPaymentEntity paginate(PosOrderPaymentEntity payment) {
		payment.setIspaging(true);
		List<PosOrderPaymentEntity> payments = this.posOrderPaymentEntityMapper.findByEntity(payment);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
		for (PosOrderPaymentEntity p : payments) {
			if (p.getPayTime() != null)
				p.setTime(sdf.format(p.getPayTime()));
		}
		payment.setResults(payments);
		return payment;
	}

	public List<HisOrderEntity> getHisOrderEntityList(List<String> memberIdList, String op) {
		return posOrderPaymentEntityMapper.getHisOrderEntityList(memberIdList, op);
	}

	@Override
	public List<PosOrderPaymentEntity> findByThOrderPk(String orderId) throws Exception {
		return this.posOrderPaymentEntityMapper.findByThOrderPk(orderId);
	}

	@Override
	public PosOrderPaymentEntity getMemLastPayment(String memId) {
		List<CusGuaEntity> guas = null;
		try {
			guas = this.memberService.findGuaByMemberId(memId);
		} catch (RDPException e) {
			e.printStackTrace();
		}
		List<String> memIds = new ArrayList<String>();
		if (guas != null)
			for (CusGuaEntity gua : guas)
				memIds.add(gua.getPkGuaId());
		memIds.add(memId);
		return this.posOrderPaymentEntityMapper.getMemLastPayment(memIds);
	}
}
